#include "GCpShapeCache.h"

enum GFixtureType
{
	GFIXTURE_POLYGON,
	GFIXTURE_CIRCLE
};


/**
 * Body definition
 * Holds the body and the anchor point
 */
class GBodyDef : public CCObject
{
public:
	GFixtureType fixtureType;

	// for circles
	cpFloat radius;

	// for polygons
	cpVect *vertices;
	int numVertices;
};

static GCpShapeCache* shapeCache = NULL;

GCpShapeCache* GCpShapeCache::sharedShapeCache(){
    if(!shapeCache){
		shapeCache = new GCpShapeCache();
		shapeCache->init();
    }
    return shapeCache;
}

bool GCpShapeCache::init(){
	dic = CCDictionary::create();
	return true;
}

cpBody* GCpShapeCache::createBodyWithName(const char* name,cpSpace* space,int collType,int group,int layers){
	GBodyDef* def = (GBodyDef*)dic->objectForKey(name);
    cpBody *body = NULL;
	cpShape* shape = NULL;
    if(def->fixtureType == GFIXTURE_CIRCLE)
    {
		body = cpBodyNew(1, 1);
        shape = cpCircleShapeNew(body, def->radius, cpvzero);
    }else{
		body = cpBodyNew(100,1);
        shape = cpPolyShapeNew(body, def->numVertices, def->vertices, cpvzero);
    }        
	cpSpaceAddBody(space, body);
	shape->sensor = true;
	shape->group = group;
	shape->layers = layers;
	shape->collision_type = collType;
	cpSpaceAddShape(space, shape);    
    return body;
}


bool GCpShapeCache::addShapesWithFile(const char* plist)
{
	CCDictionary *dictionary = CCDictionary::createWithContentsOfFile(plist);
    CCDictionary *metadataDict = (CCDictionary*)dictionary->objectForKey("metadata");
    CCDictionary *bodyDict = (CCDictionary*)dictionary->objectForKey("bodies");
	CCArray* bodiesName = bodyDict->allKeys();
	
	for (int i = 0; i < bodiesName->count(); i++){
		GBodyDef* bodyDef = new GBodyDef();
		CCString* bodyName = (CCString*)bodiesName->objectAtIndex(i);
		dic->setObject(bodyDef,bodyName->getCString());
        CCDictionary *bodyData = (CCDictionary*)bodyDict->objectForKey(bodyName->getCString());
        CCArray *fixtureList = (CCArray*)bodyData->objectForKey("fixtures");
		CCLog("%d",fixtureList->count());
		CCDictionary *fixtureData = (CCDictionary*)fixtureList->objectAtIndex(0);
		CCArray* fixtureType = (CCArray*)fixtureData->objectForKey("polygons");
        if(fixtureType != NULL){
            CCArray *polygonsArray = (CCArray*)fixtureType->objectAtIndex(0);
                
            bodyDef->fixtureType = GFIXTURE_POLYGON;
            bodyDef->numVertices = polygonsArray->count();
			cpVect *vertices = new cpVect();
			bodyDef->vertices = vertices;
			for (int j = 0; j < polygonsArray->count(); j++){
				CCString* pointString = (CCString*)polygonsArray->objectAtIndex(j);
				CCPoint offset = CCPointFromString(pointString->getCString());
				vertices[j].x = offset.x ; 
				vertices[j].y = offset.y ; 
            }
        }else{
            bodyDef->fixtureType = GFIXTURE_CIRCLE;
                
            CCDictionary *circleData = (CCDictionary *)fixtureData->objectForKey("circle");
			CCDouble* radius = (CCDouble*)circleData->objectForKey("radius"); 
            bodyDef->radius = radius->getValue();
        }
    }
    return true;
}